#!/usr/bin/env python3
import time
import os
import sys
import curses
from curses import wrapper
import argparse
from datetime import datetime, timedelta
import subprocess

class PomodoroTimer:
    def __init__(self, work_time=25, short_break=5, long_break=15, cycles=4):
        """
        Инициализация таймера Pomodoro
        
        Args:
            work_time (int): продолжительность рабочего периода в минутах
            short_break (int): продолжительность короткого перерыва в минутах
            long_break (int): продолжительность длинного перерыва в минутах
            cycles (int): количество циклов до длинного перерыва
        """
        self.work_time = work_time * 60
        self.short_break = short_break * 60
        self.long_break = long_break * 60
        self.cycles = cycles
        self.current_cycle = 1
        self.total_completed = 0
        self.stats = {'work': 0, 'short_break': 0, 'long_break': 0}
        
    def format_time(self, seconds):
        """Преобразует секунды в формат MM:SS"""
        minutes, seconds = divmod(seconds, 60)
        return f"{minutes:02d}:{seconds:02d}"
    
    def get_progress_bar(self, current, total, width=50):
        """Создает красивую полосу прогресса"""
        progress = int(width * current / total) if total > 0 else 0
        return "█" * progress + "░" * (width - progress)
    
    def send_notification(self, title, message, urgency="normal", sound=True):
        """Отправляет уведомление через notify-send с звуком"""
        try:
            # Отправка уведомления
            subprocess.run([
                "notify-send",
                f"--urgency={urgency}",
                f"--icon=appointment-soon",
                title,
                message
            ])
            
            # Воспроизведение звука с помощью системного звонка
            if sound:
                # Используем paplay для воспроизведения системного звука (если доступно)
                try:
                    # Стандартные звуки уведомлений в Linux
                    sound_files = [
                        "/usr/share/sounds/freedesktop/stereo/complete.oga",
                        "/usr/share/sounds/ubuntu/stereo/message.ogg",
                        "/usr/share/sounds/gnome/default/alerts/glass.ogg"
                    ]
                    
                    # Проверяем существование файлов и воспроизводим первый найденный
                    for sound_file in sound_files:
                        if os.path.exists(sound_file):
                            subprocess.run(["paplay", sound_file], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
                            break
                    else:
                        # Если ни один файл не найден, используем системный звуковой сигнал
                        sys.stdout.write('\a')
                        sys.stdout.flush()
                        
                except Exception:
                    # В случае ошибки используем системный звуковой сигнал
                    sys.stdout.write('\a')
                    sys.stdout.flush()
        except Exception as e:
            # Если notify-send не доступен, используем системный звуковой сигнал
            sys.stdout.write('\a')
            sys.stdout.flush()
    
    def run(self, stdscr):
        """Основной метод выполнения таймера Pomodoro с использованием curses"""
        # Инициализация curses
        curses.curs_set(0)  # Скрыть курсор
        curses.start_color()
        curses.use_default_colors()
        
        # Определить цветовые пары
        curses.init_pair(1, curses.COLOR_GREEN, -1)  # Рабочий режим
        curses.init_pair(2, curses.COLOR_CYAN, -1)   # Короткий перерыв
        curses.init_pair(3, curses.COLOR_BLUE, -1)   # Длинный перерыв
        curses.init_pair(4, curses.COLOR_YELLOW, -1) # Заголовки
        curses.init_pair(5, curses.COLOR_RED, -1)    # Кнопка выхода
        
        # Получить размеры терминала
        max_y, max_x = stdscr.getmaxyx()
        
        # Установить режим неблокирующего ввода
        stdscr.nodelay(True)
        
        # Отправить начальное уведомление
        self.send_notification("Pomodoro Timer", "Таймер запущен! Начинаем работу.", "normal", True)
        
        try:
            while True:
                # Работа
                self._run_timer(stdscr, "РАБОТА", self.work_time, curses.color_pair(1))
                self.stats['work'] += 1
                self.total_completed += 1
                
                # Проверка, нужен ли длинный перерыв
                if self.current_cycle == self.cycles:
                    # Уведомление о длинном перерыве
                    self.send_notification(
                        "Pomodoro - Длинный перерыв!", 
                        f"Работа завершена! Время для длинного перерыва ({self.long_break // 60} минут).",
                        "critical",
                        True
                    )
                    
                    # Длинный перерыв
                    self._run_timer(stdscr, "ДЛИННЫЙ ПЕРЕРЫВ", self.long_break, curses.color_pair(3))
                    self.stats['long_break'] += 1
                    self.current_cycle = 1
                    
                    # Уведомление о завершении длинного перерыва
                    self.send_notification(
                        "Pomodoro - Перерыв окончен!", 
                        "Длинный перерыв завершен! Пора вернуться к работе.",
                        "critical",
                        True
                    )
                else:
                    # Уведомление о коротком перерыве
                    self.send_notification(
                        "Pomodoro - Короткий перерыв!", 
                        f"Работа завершена! Время для короткого перерыва ({self.short_break // 60} минут).",
                        "normal",
                        True
                    )
                    
                    # Короткий перерыв
                    self._run_timer(stdscr, "КОРОТКИЙ ПЕРЕРЫВ", self.short_break, curses.color_pair(2))
                    self.stats['short_break'] += 1
                    self.current_cycle += 1
                    
                    # Уведомление о завершении короткого перерыва
                    self.send_notification(
                        "Pomodoro - Перерыв окончен!", 
                        "Короткий перерыв завершен! Пора вернуться к работе.",
                        "normal",
                        True
                    )
                    
        except KeyboardInterrupt:
            # Уведомление о завершении работы
            self.send_notification(
                "Pomodoro - Завершено", 
                f"Сессия завершена! Выполнено циклов: {self.total_completed}",
                "low",
                True
            )
            return
        
    def _run_timer(self, stdscr, label, duration, color_pair):
        """Запускает один таймер (работа или перерыв)"""
        stdscr.clear()
        max_y, max_x = stdscr.getmaxyx()
        
        # Время старта и окончания
        start_time = datetime.now()
        end_time = start_time + timedelta(seconds=duration)
        
        # Отображение основной информации
        while datetime.now() < end_time:
            remaining = int((end_time - datetime.now()).total_seconds())
            if remaining < 0:
                break
                
            # Очистить экран и обновить данные
            stdscr.clear()
            
            # Получить текущие размеры окна (на случай изменения размера)
            current_y, current_x = stdscr.getmaxyx()
            
            # Заголовок с цветом
            title = f"🍅 POMODORO TIMER 🍅"
            stdscr.addstr(2, (current_x - len(title)) // 2, title, curses.color_pair(4) | curses.A_BOLD)
            
            # Текущий статус с соответствующим цветом
            status = f"[ {label} ]"
            stdscr.addstr(4, (current_x - len(status)) // 2, status, color_pair | curses.A_BOLD)
            
            # Отображение времени крупными цифрами
            time_str = self.format_time(remaining)
            stdscr.addstr(6, (current_x - len(time_str)) // 2, time_str, color_pair | curses.A_BOLD)
            
            # Полоса прогресса
            progress = 1.0 - (remaining / duration)
            bar_width = min(current_x - 10, 50)
            progress_bar = self.get_progress_bar(progress * duration, duration, bar_width)
            stdscr.addstr(8, (current_x - len(progress_bar)) // 2, progress_bar, color_pair)
            
            # Процент выполнения
            percent = f"{progress * 100:.0f}%"
            stdscr.addstr(9, (current_x - len(percent)) // 2, percent, color_pair)
            
            # Информация о циклах
            cycle_info = f"Цикл: {self.current_cycle}/{self.cycles} | Всего завершено: {self.total_completed}"
            stdscr.addstr(11, (current_x - len(cycle_info)) // 2, cycle_info)
            
            # Время окончания
            end_info = f"Окончание: {end_time.strftime('%H:%M:%S')}"
            stdscr.addstr(12, (current_x - len(end_info)) // 2, end_info)
            
            # Статистика
            stats_info = f"Работа: {self.stats['work']} | Короткие перерывы: {self.stats['short_break']} | Длинные перерывы: {self.stats['long_break']}"
            if current_x > len(stats_info) + 4:
                stdscr.addstr(13, (current_x - len(stats_info)) // 2, stats_info)
            
            # Управление
            controls = "Нажмите 'q' для выхода, пробел для паузы/продолжения"
            if current_y > 15 and current_x > len(controls) + 4:
                stdscr.addstr(current_y - 2, (current_x - len(controls)) // 2, controls)
            
            # Уведомление о скором завершении
            if remaining == 60:  # За минуту до конца
                self.send_notification(
                    f"Pomodoro - Скоро завершение", 
                    f"Осталась 1 минута до завершения периода: {label}",
                    "normal",
                    True
                )
            
            # Обработка ввода
            key = stdscr.getch()
            if key == ord('q'):
                raise KeyboardInterrupt
            elif key == ord(' '):
                # Пауза
                pause_start = datetime.now()
                stdscr.addstr(current_y // 2, (current_x - 12) // 2, "⏸️  ПАУЗА  ⏸️", curses.color_pair(5) | curses.A_BOLD)
                self.send_notification("Pomodoro - Пауза", "Таймер на паузе. Нажмите любую клавишу для продолжения.", "low", True)
                stdscr.nodelay(False)  # Включить блокирующий ввод для паузы
                stdscr.getch()  # Ждать нажатия клавиши
                stdscr.nodelay(True)  # Вернуть неблокирующий ввод
                pause_duration = datetime.now() - pause_start
                end_time += pause_duration  # Добавить время паузы к времени окончания
                self.send_notification("Pomodoro - Продолжение", "Таймер снова запущен!", "low", True)
            
            # Обновить экран
            stdscr.refresh()
            time.sleep(0.1)
        
        # Уведомление о завершении
        for _ in range(3):  # Мигание уведомления
            stdscr.clear()
            stdscr.addstr(current_y // 2, (current_x - 20) // 2, f"{label} ЗАВЕРШЕН!", color_pair | curses.A_BOLD)
            stdscr.refresh()
            time.sleep(0.3)
            stdscr.clear()
            stdscr.refresh()
            time.sleep(0.2)

def main():
    parser = argparse.ArgumentParser(description='Терминальный таймер Pomodoro')
    parser.add_argument('-w', '--work', type=int, default=25, help='Продолжительность работы (минуты)')
    parser.add_argument('-s', '--short', type=int, default=5, help='Продолжительность короткого перерыва (минуты)')
    parser.add_argument('-l', '--long', type=int, default=15, help='Продолжительность длинного перерыва (минуты)')
    parser.add_argument('-c', '--cycles', type=int, default=4, help='Количество циклов до длинного перерыва')
    
    args = parser.parse_args()
    
    pomodoro = PomodoroTimer(args.work, args.short, args.long, args.cycles)
    wrapper(pomodoro.run)

if __name__ == "__main__":
    main()